using System;

namespace NFreeMarker.Core
{
    /**
     * Represents a &lt;return&gt; instruction to jump out of a macro.
     * @author <A HREF="mailto:jon@revusky.com">Jonathan Revusky</A>
     */

    public sealed class ReturnInstruction : TemplateElement
    {
        private readonly Expression _exp;

        internal ReturnInstruction(Expression exp)
        {
            _exp = exp;
        }

        internal override void Accept(Environment env)
        {
            if (_exp != null)
            {
                env.SetLastReturnValue(_exp.GetAsTemplateModel(env));
            }
            if (NextSibling() != null)
            {
                // We need to jump out using an exception.
                throw Return.Instance;
            }
            //if (!(GetParent() is Macro || GetParent().GetParent() is Macro))
            //{
            //    // Here also, we need to jump out using an exception.
            //    throw Return.Instance;
            //}
            throw new NotImplementedException();
        }

        public override string GetCanonicalForm()
        {
            string expString = _exp == null ? "" : " " + _exp.GetCanonicalForm();
            return "<#return" + expString + "/>";
        }

        public override string GetDescription()
        {
            return "return" + " [" + GetStartLocation() + "]";
        }

        public class Return : ApplicationException
        {
            internal static readonly Return Instance = new Return();

            private Return()
            {
            }
        }
    }
}